﻿/*
 * aspark
 * Email:mwyso@126.com
 * http://quicksl.codeplex.com/
 */

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;

using System.Linq;

namespace QuickSL
{
    internal class TouchState : IDisposable
    {
        private ManualResetEvent _touchEvent = null;

        private TouchState() 
        {
            _touchEvent = new ManualResetEvent(true);
            Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported);
#if DEBUG
            Application.Current.RootVisual.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler((obj,e) =>
            {
                IsTouched = true;
            }), true);

            Application.Current.RootVisual.AddHandler(UIElement.MouseLeftButtonUpEvent, new MouseButtonEventHandler((obj, e) =>
            {
                IsTouched = false;
            }), true);
#endif
        }

        private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
        {
            if (e.GetTouchPoints(null).LastOrDefault().Action == TouchAction.Up)
            {
                IsTouched = false;
            }
            else
                IsTouched = true;
        }

        /// <summary>
        /// create the touchstate instant on ui thread
        /// </summary>
        /// <returns></returns>
        private static TouchState Create()
        {
            AutoResetEvent evt = new AutoResetEvent(false);
            TouchState state = null;
            Common.CurrentDispatcher.BeginInvoke(() =>
            {
                state = new TouchState();
                evt.Set();
            });
            evt.WaitOne();

            return state;
        }

        private static object _objLock = new object();
        private static TouchState _state = null;
        /// <summary>
        /// Current TouchState
        /// </summary>
        internal static TouchState Current
        {
            get
            {
                if (_state == null)
                {
                    lock (_objLock)
                    {
                        if (_state == null)
                        {
                            _state = TouchState.Create();
                        }
                    }
                }
                return _state;
            }
        }

        /// <summary>
        /// block and wait until touch up
        /// </summary>
        public void WaitOne()
        {
            _touchEvent.WaitOne();
        }

        private bool _isTouched = false;

        /// <summary>
        /// has touched the screen
        /// </summary>
        public bool IsTouched
        {
            get {
                return _isTouched;
            }
            private set {
                lock (this)
                {
                    _isTouched = value;
                }

                if (_isTouched)
                    _touchEvent.Reset();
                else
                    _touchEvent.Set();

                //OnIsBusyChanged(new EventArgs());
            }
        }

        ///// <summary>
        ///// IsTouched has changed
        ///// </summary>
        //public event EventHandler IsTouchedChanged;

        //private void OnIsTouchedChanged(EventArgs e)
        //{
        //    if (IsTouchedChanged != null)
        //    {
        //        IsTouchedChanged(this, e);
        //    }
        //}

        #region IDisposable Members

        public void Dispose()
        {
            Touch.FrameReported -= new TouchFrameEventHandler(Touch_FrameReported);
        }

        #endregion
    }

    //public class IsTouchedChangedEventArgs : EventArgs
    //{
    //    public bool Value { get; private set; }

    //    public IsTouchedChangedEventArgs()
    //    {

    //    }
    //}
}
